package com.haisen.service.impl;

import com.alibaba.fastjson.JSON;
import com.dingtalk.api.response.OapiDepartmentListResponse;
import com.haisen.core.utils.Constants;
import com.haisen.dataobject.dto.TreeDto;
import com.haisen.dataobject.entity.Organization;
import com.haisen.dataobject.mapper.base.OrganizationMapper;
import com.haisen.service.OrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.beans.Transient;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrganizationServiceImpl implements OrganizationService {

    @Autowired
    private OrganizationMapper organizationMapper;

    @Override
    @Transactional
    public void createOrganization(Organization organization) {
        //查找父节点
        Organization parent = findOne(organization.getParentId());
        //将父节点和和爷爷节点拼凑起来
        organization.setParentIds(parent.makeSelfAsParentIds());
        organization.setAvailable(true);
        organizationMapper.insertSelective(organization);
    }

    @Override
    @Transactional
    public void updateOrganization(Organization organization) {
        organizationMapper.updateByPrimaryKeySelective(organization);
    }

    @Override
    @Transactional
    public void deleteOrganization(Long organizationId) {
        organizationMapper.deleteByPrimaryKey(organizationId);
    }

    @Override
    public Organization findOne(Long organizationId) {
        return organizationMapper.selectByPrimaryKey(organizationId);
    }

    @Override
    public List<Organization> findAll() {
        return organizationMapper.selectAll();
    }

    @Override
    public List<Organization> find(Weekend example) {
        return organizationMapper.selectByExample(example);
    }

    @Override
    public List<TreeDto> findOrgTree(Long pId) {
        if (StringUtils.isEmpty(pId)) {
            pId = Constants.ORG_ROOT_ID;
        }
        List<TreeDto> tds = new ArrayList<>();
        /* Weekend example = Weekend.of(Organization.class);
        WeekendCriteria<Organization, Object> criteria = example.weekendCriteria();
        criteria.andEqualTo(Organization::getParentId, pId);
        //新增了负责人和手机号码，传递过去
       organizationMapper.selectByExample(example).forEach(o ->
            tds.add(new TreeDto(o.getId(), o.getParentId(), o.getName(), Boolean.FALSE.equals(o.getLeaf()), o)));*/
       organizationMapper.selectWithUserByPid(pId).forEach(o ->
                tds.add(new TreeDto(o.getId(), o.getParentId(), o.getName(), Boolean.FALSE.equals(o.getLeaf()), o)));
        return tds;
    }

    @Override
    public List<Organization> findAllWithExclude(Organization exclude) {
        Weekend weekend = Weekend.of(Organization.class);
        WeekendCriteria<Organization, Object> criteria = weekend.weekendCriteria();
        //排除自己和自己的子节点
        criteria.andNotEqualTo(Organization::getId, exclude.getId()).andNotLike(Organization::getParentIds, exclude.makeSelfAsParentIds() + "%");
        return organizationMapper.selectByExample(weekend);
    }

    @Override
    @Transactional
    public void move(Organization source, Organization target) {
        organizationMapper.updateByPrimaryKeySelective(target);
        organizationMapper.updateSalefParentIds(source.makeSelfAsParentIds());
    }


   @Override
   @Transient
    public void createOrUpdate(List<OapiDepartmentListResponse.Department> departmentList){

       //将组织结构转换
       List<Organization> organizationList = departmentList.stream().map(o ->{
           return new Organization(o.getId(),o.getName(),o.getParentid());
       }).collect(Collectors.toList());
       //根据departmentList生成parentids的路径，可能要用到递归

       //插入到organzition
       organizationList.forEach( o ->{
           getparentids(organizationList,o);
           //此反转是所有的反转了
           o.setParentIds(reverseSb(sb));
           //清空
           sb.delete(0,sb.length());
           log.info("同步更新的组织机构：{}",JSON.toJSONString(o));
          createOrUpdate(o);
       });
   }


   //todo:递归查询未完成
   //获取组织parent_ids，有当前节点去找父节点
    StringBuilder sb = new StringBuilder();
   private void getparentids(List<Organization> organizationList ,Organization org){
           sb.append("/"+org.getId());
        //根节点为0，例如0/1,0节点实际不存在的
        if (org.getParentId().intValue() !=0 ){
            Organization orgparent = getParent(organizationList,org.getParentId());
             if (orgparent != null) {
                 //log.info("子节点{},父节点:{}", JSON.toJSONString(org), JSON.toJSONString(orgparent));
                 getparentids(organizationList, orgparent);
             } else {
                 sb.append("/1/0");
             }
        }
   }

   private Organization getParent(List<Organization> organizationList,Long pid){
      List<Organization>  organizations = organizationList.stream().filter( o ->{
            if (o.getId().equals(pid)) return true;
            else return false;
        }).limit(1)
          .collect(Collectors.toList());
        return organizations.size() > 0 ? organizations.get(0) : null;
   }



   private void createOrUpdate(Organization organization){
       if (organizationMapper.selectByPrimaryKey(organization.getId()) == null){
           organizationMapper.insertSelective(organization);
       } else {
           organizationMapper.updateByPrimaryKeySelective(organization);
       }
   }


    @Override
    public List<String> findByIds(Long[] ids) {
        Weekend<Organization> example = Weekend.of(Organization.class);
        WeekendCriteria<Organization,Object> criteria = example.weekendCriteria();
        criteria.andIn(Organization::getId, Arrays.asList(ids));
      List<String> orgNoList  = organizationMapper.selectByExample(example).stream()
                .map(o ->{
                    return o.getNo();
                }).collect(Collectors.toList());
        return orgNoList;
    }

    private String reverseSb(StringBuilder sb){
       StringBuilder retsb = new StringBuilder();
       String[] arrparse = sb.toString().split("/");
       List<String> listparse = Arrays.asList(arrparse);
        Collections.reverse(listparse);
        //将list封装用/分隔成字符串
        listparse.stream().map( o ->{
            if(!StringUtils.isEmpty(o))
                retsb.append(o+"/");
            return retsb;
        }).collect(Collectors.toList());

        if (retsb.length() > 0) {
            retsb.deleteCharAt(retsb.length() - 1);
        }
       return retsb.toString();
    }
}
